package com.pan.admin.module.test.service.impl;

import com.alibaba.fastjson.TypeReference;
import com.gitee.apanlh.util.algorithm.digest.MD5;
import com.gitee.apanlh.util.algorithm.encrypt.symmetric.AES;
import com.gitee.apanlh.util.base.CollUtils;
import com.gitee.apanlh.util.base.Eq;
import com.gitee.apanlh.util.base.IteratorUtils;
import com.gitee.apanlh.util.base.MapUtils;
import com.gitee.apanlh.util.dataformat.JsonUtils;
import com.gitee.apanlh.util.encode.HexUtils;
import com.gitee.apanlh.util.id.IdUtils;
import com.gitee.apanlh.util.net.http.HttpClientBuilder;
import com.gitee.apanlh.util.net.http.HttpResponse;
import com.gitee.apanlh.util.reflection.ClassConvertUtils;
import com.gitee.apanlh.util.valid.ValidParam;
import com.gitee.apanlh.web.http.HttpMethod;
import com.gitee.apanlh.web.model.vo.ResultVO;
import com.pan.admin.cache.DistrictCache;
import com.pan.admin.cache.FormLocalCache;
import com.pan.admin.common.constant.ProductPlanVersionModeEnum;
import com.pan.admin.common.constant.redis.ApiTestRedis;
import com.pan.admin.common.constant.test.ApiTestKeyConstant;
import com.pan.admin.common.constant.test.ApiTestTypeEnum;
import com.pan.admin.module.common.entity.DistrictPO;
import com.pan.admin.module.form.entity.FormPO;
import com.pan.admin.module.loanProduct.dao.LoanProductPlanDao;
import com.pan.admin.module.loanProduct.entity.LoanProductPlan;
import com.pan.admin.module.test.context.ApiTextContent;
import com.pan.admin.module.test.entity.ApiTestSend;
import com.pan.admin.module.test.entity.ApiTestUserInfo;
import com.pan.admin.module.test.entity.ApiUserInfo;
import com.pan.admin.module.test.entity.vo.ApiTestUserFormRadioVO;
import com.pan.admin.module.test.entity.vo.ApiTestUserFormVO;
import com.pan.admin.module.test.message.ApiTestMessage;
import com.pan.admin.module.test.message.ApiTestResultMessage;
import com.pan.admin.module.test.service.ApiTestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
public class ApiTestServiceImpl implements ApiTestService {

    @Autowired
    private ApiTextContent apiTextContent;
    @Autowired
    private LoanProductPlanDao loanProductPlanDao;

    @Override
    public ApiTestResultMessage sendTest(ApiTestSend apiTestSend, ApiTestTypeEnum apiTestTypeEnum) {
        String serverUrl = apiTextContent.getServerUrl(apiTestTypeEnum);

        //  聚合字段
        Map<String, String> convertMap = MapUtils.newHashMap();
        List<ApiTestUserInfo> listUserInfo = apiTestSend.getListUserInfo();
        List<ApiTestUserInfo> listUserFormInfo = apiTestSend.getListUserFormInfo();

        IteratorUtils.array(listUserInfo, apiTestUserInfo -> convertMap.put(apiTestUserInfo.getFieldName(), apiTestUserInfo.getFieldValue()));
        IteratorUtils.array(listUserFormInfo, apiTestUserInfo -> convertMap.put(apiTestUserInfo.getFieldName(), apiTestUserInfo.getFieldValue()));

        //  获取计划对象
        Long productPlanId = apiTestSend.getProductPlanId();
        LoanProductPlan productPlanPO = loanProductPlanDao.getById(productPlanId);

        //  转换apiUserInfo对象
        ApiUserInfo apiUserInfo = ClassConvertUtils.toBean(convertMap, ApiUserInfo.class);
        apiUserInfo.setReqId(IdUtils.snowFlakeIdStr());
        apiUserInfo.setPhoneMd5(MD5.create().digestToHex(apiUserInfo.getPhone()));
        DistrictPO districtPO = DistrictCache.getByName(apiUserInfo.getCity());
        apiUserInfo.setAreaCode(districtPO.getCode());
        apiUserInfo.setProvinceName(districtPO.getProvinceName());
        apiUserInfo.setProvinceCode(districtPO.getProvinceCode());
        apiUserInfo.setProductId(productPlanPO.getLoanProductId());
        apiUserInfo.setProductPlanId(productPlanPO.getId());

        //  掩码模式设置值
        if (Eq.objectOr(productPlanPO.getVersionMode(),
                ProductPlanVersionModeEnum.PHONE_MASK_8.getVersionMode(),
                ProductPlanVersionModeEnum.PHONE_MASK_9.getVersionMode(),
                ProductPlanVersionModeEnum.PHONE_MASK_10.getVersionMode())) {

            ProductPlanVersionModeEnum productPlanVersionModeEnum = ProductPlanVersionModeEnum.getEnum(productPlanPO.getVersionMode());
            String phone = apiUserInfo.getPhone();
            String phoneMask = phone.substring(0, productPlanVersionModeEnum.getCutSize());
            apiUserInfo.setPhoneMask(phoneMask);
        }

        //  封装数据对象
        ApiTestMessage apiTestMessage = new ApiTestMessage();
        apiTestMessage.setTestType(apiTestSend.getTestType());
        apiTestMessage.setTestModeType(apiTestSend.getTestModeType());
        apiTestMessage.setProductPlanId(apiTestSend.getProductPlanId());
        apiTestMessage.setChannelUniqueCode(apiTestSend.getChannelUniqueCode());
        apiTestMessage.setApiClientId(apiTestSend.getApiClientId());
        apiTestMessage.setApiUserInfo(apiUserInfo);

        //  加密参数
        String json = JsonUtils.toJson(apiTestMessage);
        AES ecb = AES.createEcb(HexUtils.decode(ApiTestKeyConstant.KEY));
        String data = ecb.encryptToHex(json);
        Map<String, String> sendData = MapUtils.newHashMap(newMap -> newMap.put("data", data));

        //  发起测试流程
        HttpResponse httpResponse = HttpClientBuilder.builder(serverUrl, HttpMethod.POST).withBodyJson(sendData).build();

        //  返回结果
        String resultBody = httpResponse.getStr();
        ResultVO<ApiTestResultMessage> resultVO = JsonUtils.toBean(resultBody, new TypeReference<>() {});
        ApiTestResultMessage resultMessage = resultVO.getData();
        //  如果返回结果不存在新增服务端响应
        if (ValidParam.isNull(resultMessage)) {
            resultMessage = new ApiTestResultMessage();
        }

        resultMessage.setCode(resultVO.getCode());
        resultMessage.setMsg(resultVO.getMsg());
        return resultMessage;
    }

    @Override
    public List<ApiTestUserFormVO> listUserForm() {
        //  获取所有表单项
        Map<String, List<FormPO>> allUserFormCache = FormLocalCache.getAllUserFormCache();

        List<ApiTestUserFormVO> listApiTestUserFormVO = CollUtils.newArrayList(allUserFormCache.size());

        //  封装对象
        IteratorUtils.entrySet(allUserFormCache, (fieldName, listFormItem) -> {
            //  过滤年龄/性别
            if ("age".equals(fieldName)) {
                return ;
            }

            ApiTestUserFormVO apiTestUserFormVO = new ApiTestUserFormVO();
            apiTestUserFormVO.setFieldName(fieldName);

            //  获取字段中文名称
            String fieldChineseName = listFormItem.getFirst().getFieldName();
            apiTestUserFormVO.setFieldChineseName(fieldChineseName);

            //  设置多选框值
            List<ApiTestUserFormRadioVO> listRadioVO = CollUtils.newArrayList();
            for (int i = 0; i < listFormItem.size(); i++) {
                FormPO formPO = listFormItem.get(i);
                ApiTestUserFormRadioVO apiTestUserFormRadioVO = new ApiTestUserFormRadioVO();
                apiTestUserFormRadioVO.setValue(formPO.getMappingValue());
                apiTestUserFormRadioVO.setRemark(formPO.getFieldValue());
                listRadioVO.add(apiTestUserFormRadioVO);
            }
            apiTestUserFormVO.setListRadio(listRadioVO);

            listApiTestUserFormVO.add(apiTestUserFormVO);
        });
        return listApiTestUserFormVO;
    }

    @Override
    public String genTestPhone() {
        //  获取redis中是否存在值
        ApiTestRedis.PHONE.setIfAbsent("phone", 13899999999L);
        //  每次递减
        Long value = ApiTestRedis.PHONE.get("phone", Long.class) - 1;
        ApiTestRedis.PHONE.set("phone", value);
        return value.toString();
    }
}
